home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / graphics / vlapak1.zip / TSR_VLA.ZIP / TSR.ASM < prev    next >
Assembly Source File  |  1993-08-19  |  10KB  |  331 lines

  1.     IDEAL
  2.     MODEL Tiny          ;TINY, cause we are making a COM file
  3. ────────────────────────────────────────────────────────────────────────────
  4.     CODESEG
  5.     LOCALS
  6.     P386n
  7.     
  8.     MASM
  9.     .STARTUP        ;in a COM file, CS = SS = DS = ES = PSPseg at startup
  10.                     ;I used .STARTUP here cause I couldn't get it
  11.                     ;to do a com file otherwise... =(
  12.     IDEAL
  13.  
  14.     mov     sp,offset StackArea + 200h  ;setup 200h byte stack (for setup
  15.                                         ; only!)
  16.     jmp     Init_TSR                    ;Start TSR!
  17.  
  18. ────────────────────────────────────────────────────────────────────────────
  19. ; We put all our PERMANENT data right here...
  20. ────────────────────────────────────────────────────────────────────────────
  21. MultiIdent  =       0D7h    ;our identifier - can be any value >= D7h?
  22. ENVoff      =       2ch     ;offset in PSP seg to ENVironment block seg
  23. TrueCode    =       0fed8h  ;a double check to make sure it's our guy
  24.                             ; that's installed
  25.  
  26. PSPseg      dw      ?       ;ES at the beginning of execution
  27.  
  28. OldInt10h   dd      ?       ;intercept BIOS calls to detect mode changes
  29. OldInt1Ch   dd      ?       ;this is called by timer interrupt 8 (IRQ 0)
  30. OldInt2fh   dd      ?       ;this is the old multi-plex interrupt
  31.  
  32. TimerActive db      2       ;0= do nothing, not in TEXT video mode
  33.                             ;1= display time and message.
  34.  
  35. Other_Stack dd      ?       ;save stack SS:SP here
  36. Our_Stack   dd      ?
  37. ────────────────────────────────────────────────────────────────────────────
  38.     ────────────────────────────────────────────────────────────────────
  39.     ; This new Int 10h is just to detect mode changes
  40.     ────────────────────────────────────────────────────────────────────
  41. PROC Int_10h FAR
  42.     pushf
  43.     call    [DWORD CS:OldInt10h]    ;execute the interrupt
  44.  
  45.     mov     [cs:TimerActive],0      ;assume it GRAPH mode
  46.  
  47.     push    ds bx
  48.  
  49.     xor     bx,bx
  50.     mov     ds,bx
  51.  
  52.     mov     bl,[ds:449h]            ;get video mode
  53.     cmp     bl,3
  54.     ja      short @@IsGraph
  55.     
  56.     mov     [cs:TimerActive],1
  57.     
  58. @@IsGraph:
  59.  
  60.     pop     bx ds
  61.     iret
  62. ENDP
  63.     ────────────────────────────────────────────────────────────────────
  64.     ; This Int 1Ch handler does all the dirty work
  65.     ────────────────────────────────────────────────────────────────────
  66. PROC Int_1Ch FAR
  67.     cmp     [CS:TimerActive],0
  68.     je      @@END
  69.     
  70.     cli                     ;an interrupt MAY crash the computer...
  71.                             ; cause we're messing with the stack
  72.  
  73.     mov     [WORD HIGH cs:Other_Stack],ss       ;setup our stack
  74.     mov     [WORD LOW  cs:Other_Stack],sp
  75.     lss     sp,[cs:Our_Stack]
  76.  
  77.     push    es cx ax dx di
  78.     cld
  79.     
  80.     mov     ax,0b800h
  81.     mov     es,ax
  82.     mov     di,(80-8) * 2   ;upper right side
  83.  
  84.     mov     ah,2        ;read real time clock
  85.     int     1ah         ;CH = hours in BCD
  86.                         ;CL = minutes, DH= seconds
  87.     
  88.     mov     ah,021h         ;color blue on green (LAME!)
  89.     mov     al,ch
  90.     shr     al,4
  91.     add     al,"0"
  92.     stosw
  93.     mov     al,ch           ;print hours
  94.     and     al,00001111b
  95.     add     al,"0"
  96.     stosw
  97.  
  98.     mov     al,":"
  99.     stosw
  100.     
  101.     mov     al,cl
  102.     shr     al,4
  103.     add     al,"0"
  104.     stosw
  105.     mov     al,cl           ;print minutes
  106.     and     al,00001111b
  107.     add     al,"0"
  108.     stosw
  109.  
  110.     mov     al,":"
  111.     stosw
  112.     
  113.     mov     al,dh
  114.     shr     al,4
  115.     add     al,"0"
  116.     stosw
  117.     mov     al,dh           ;print seconds
  118.     and     al,00001111b
  119.     add     al,"0"
  120.     stosw
  121.  
  122.     pop     di dx ax cx es
  123.     
  124.     lss     sp,[cs:Other_Stack]     ;restore other guys stack
  125.     sti
  126.     
  127. @@END:
  128.     jmp     [DWORD cs:OldInt1Ch]    ;do original interrupt
  129. ENDP
  130.     ────────────────────────────────────────────────────────────────────
  131.     ; call Int 2Fh with AH = MultiIdent and you will get back...
  132.     ;
  133.     ; If TSR is installed...
  134.     ;OUT:   CF= 0
  135.     ;       AX= TRUECODE 
  136.     ;       BX= PSP seg     (use to release memory block)
  137.     ;       CX= CS          (use to access variables)
  138.     ;
  139.     ; If TSR was NOT previously installed...
  140.     ;OUT:   AH= <unchanged>
  141.     ;       CF= 1
  142.     ────────────────────────────────────────────────────────────────────
  143. PROC Int_2Fh FAR
  144.     cmp     ah,MultiIdent           ;is it our call?
  145.     je      short @@Its_Ours
  146.  
  147.     jmp     [DWORD cs:OldInt2Fh]    ;nope, let it chain through
  148.  
  149. @@Its_Ours:
  150.     mov     ax,TrueCode         ;tell 'em that it's REALLY ours
  151.     mov     bx,[cs:PSPseg]      ;grab PSP segment
  152.     mov     cx,cs               ;set to current CODESEG
  153.     clc
  154.     retf 2                      ;need flags to NOT be restored
  155. ENDP
  156.     
  157.     dw  50 dup (?)          ;a VERY small stack.. enough to push all
  158.                             ;extended registers and segment regs..
  159.  
  160. LABEL The_Stack WORD    ;!!! NOTE THAT THE LABEL IS AFTER THE STACK !!!
  161.                         ;       STACKS GO DOWN!!
  162.  
  163.  
  164. ────────────────────────────────────────────────────────────────────────────
  165. ; !!!! EXERYTHING ABOVE THIS POINT REMAINS RESIDENT. BELOW GOES BYEBYE !!!!
  166. ────────────────────────────────────────────────────────────────────────────
  167. AXE_POINT:          ;where we chop the code.. =)
  168.  
  169.  
  170.  
  171.  
  172.  
  173. ────────────────────────────────────────────────────────────────────────────
  174. ────────────────────────────────────────────────────────────────────────────
  175. ; We put all our SETUP-ONLY data right here...
  176. ────────────────────────────────────────────────────────────────────────────
  177.  
  178. MSG_Installed   db  "TSR was successfully installed.",13,10,0
  179. MSG_Removed     db  "TSR is now removed.",13,10,0
  180.  
  181. ────────────────────────────────────────────────────────────────────────────
  182.     ────────────────────────────────────────────────────────────────────
  183.     ; Prints a ASCIIZ string pointed to by DS:SI
  184.     ────────────────────────────────────────────────────────────────────
  185. PROC PrintZ NEAR
  186.     push    si ax dx
  187.  
  188. @@PrLoop:
  189.     mov     dl,[si]
  190.     inc     si
  191.     or      dl,dl
  192.     je      short @@Done
  193.  
  194.     mov     ah,2
  195.     int     21h
  196.     jmp     short @@PrLoop
  197.  
  198. @@Done:
  199.     pop     dx ax si
  200.     ret
  201. ENDP
  202.  
  203.     ────────────────────────────────────────────────────────────────────
  204.     ; Initializes the TSR or, if it's already installed, removes it.
  205.     ────────────────────────────────────────────────────────────────────
  206. PROC Init_TSR NEAR
  207.     mov     ax,cs
  208.     mov     ds,ax
  209.     mov     [PSPseg],es         ;save PSPseg
  210.  
  211.     mov     [WORD LOW  Our_Stack],offset The_Stack  ;setup our stack
  212.     mov     [WORD HIGH Our_Stack],cs
  213.     
  214.     mov     ah,MultiIdent       ;check to see if we are already installed
  215.     int     2fh
  216.     jc      short @@Install     ;not there
  217.     cmp     ax,TrueCode         ;is it REALLY installed?
  218.     jne     short @@Install
  219.  
  220.     push    bx                  ;BX = PSPseg of other guy
  221.     ──
  222.     push    ds
  223.     mov     ds,cx                   ;DS = other guys CS
  224.  
  225.     mov     bx,10h                  ;uninstall other guys stuff
  226.     mov     di,offset OldInt10h     ;use same offsets, since it's the same 
  227.     call    Restore_int             ; program... =)
  228.  
  229.     mov     bx,1ch
  230.     mov     di,offset OldInt1ch
  231.     call    Restore_int
  232.  
  233.     mov     bx,2fh
  234.     mov     di,offset OldInt2fh
  235.     call    Restore_int
  236.     pop     ds
  237.     ──
  238.     pop     es          ;from BX's push.. get the PSPseg of OTHER GUY
  239.     mov     ah,49h
  240.     int     21h         ;release that memory block
  241.     
  242.     mov     ax,cs
  243.     mov     ds,ax
  244.     mov     si,offset Msg_Removed
  245.     call    PrintZ
  246.  
  247.     mov     ax,4c00h
  248.     int     21h         ;exit program
  249.  
  250. @@Install:
  251.     mov     es,[cs:ENVoff]      ;get segment of Environment block
  252.     mov     ah,49h
  253.     int     21h                 ;release it (WE DON'T NEED IT)
  254.     ──
  255.     mov     ax,cs
  256.     mov     ds,ax
  257.     
  258.     mov     bx,10h
  259.     mov     di,offset OldInt10h
  260.     mov     dx,offset Int_10h
  261.     call    Set_Int
  262.  
  263.     mov     bx,1ch
  264.     mov     di,offset OldInt1ch
  265.     mov     dx,offset Int_1ch
  266.     call    Set_Int
  267.  
  268.     mov     bx,2fh
  269.     mov     di,offset OldInt2fh
  270.     mov     dx,offset Int_2fh
  271.     call    Set_Int
  272.     ──
  273.     mov     si,offset MSG_Installed 
  274.     call    PrintZ
  275.     ──
  276.     mov     dx,offset AXE_Point
  277.     shr     dx,4
  278.     inc     dx
  279.     mov     ax,3100h            ;function KEEP (advanced TSR)
  280.     int     21h                 ; al = return code, dx = paragraphs to keep
  281. ENDP
  282.  
  283.     ────────────────────────────────────────────────────────────────────
  284.     ;   bx = interrupt # to replace
  285.     ;
  286.     ;DS:DI = where to store old interrupt
  287.     ;DS:DX = offset to new INTerrupt
  288.     ────────────────────────────────────────────────────────────────────
  289. PROC Set_Int NEAR
  290.     push    es ecx bx
  291.  
  292.     xor     cx,cx
  293.     mov     es,cx
  294.     shl     bx,2
  295.  
  296.     mov     ecx,[es:bx]     ;grab old int
  297.     mov     [di],ecx        ;save it
  298.  
  299.     cli
  300.     mov     [WORD es:bx  ],dx   ;store new int
  301.     mov     [WORD es:bx+2],ds
  302.     sti
  303.     
  304.     pop     bx ecx es
  305.     ret
  306. ENDP
  307.     ────────────────────────────────────────────────────────────────────
  308.     ;   bx = interrupt # to restore
  309.     ;
  310.     ;DS:DI = where old interrupt is stored
  311.     ────────────────────────────────────────────────────────────────────
  312. PROC Restore_Int NEAR
  313.     push    es ecx bx
  314.  
  315.     xor     cx,cx
  316.     mov     es,cx
  317.     shl     bx,2
  318.  
  319.     cli
  320.     mov     ecx,[di]        ;grab old SAVED int
  321.     mov     [es:bx],ecx     ;restore it
  322.     sti
  323.     
  324.     pop     bx ecx es
  325.     ret
  326. ENDP
  327.  
  328. StackArea:              ;where the stack for initialization goes
  329.  
  330. END
  331.